home *** CD-ROM | disk | FTP | other *** search
- /* $VER: vbcc (main.c) V0.3 */
-
- #include "vbc.h"
-
- int endok=1;
- int line,errors;
-
- char errfname[100]; /* VORSICHT: Diese Konstante kommt nochmal vor */
-
- char *multname[]={"","s"};
- void raus(void)
- /* Beendet das Programm */
- {
- if(DEBUG) printf("raus()\n");
- if(!endok) printf("unexpected end of file\n");
- if(errors) printf("%d error%s found!\n",errors,multname[errors>1]);
- while(nesting>=0) leave_block();
- if(in[0]&&(c_flags[17]&USEDFLAG)) fclose(in[0]);
- if(ppout) fclose(ppout);
- if(out) fclose(out);
- if(ic1) fclose(ic1);
- if(ic2) fclose(ic2);
- if(!(c_flags[17]&USEDFLAG)) pp_free();
- if(endok&&!errors) exit(EXIT_SUCCESS); else exit(EXIT_FAILURE);
- }
-
- int eof;
-
- void translation_unit(void)
- /* bearbeitet translation_unit */
- /* hier z.Z. nur provisorisch */
- {
- while(1){
- killsp();
- if(c_flags[18]&USEDFLAG){
- if(*s==EOF) raus();
- fputs(string,ppout);fputc('\n',ppout);
- s=string;*s=0;
- }else{
- if(eof||(!isalpha((unsigned char)*s)&&*s!='_')){
- if(!eof) error(0);
- raus();
- }
- endok=0;
- var_declaration();
- endok=1;
- }
- }
- }
-
- void dontwarn(char *p)
- /* schaltet flags fuer Meldung auf DONTWARN */
- {
- int i;
- if(*p!='=') error(4,"-dontwarn");
- i=atoi(p+1);
- if(i>=err_num) error(159,i);
- if(i<0){
- for(i=0;i<err_num;i++)
- if(!(err_out[i].flags&(ANSIV|FATAL)))
- err_out[i].flags|=DONTWARN;
- return;
- }
- if(err_out[i].flags&(ANSIV|FATAL)) error(160,i);
- err_out[i].flags|=DONTWARN;
- }
- void warn(char *p)
- /* schaltet Warnung fuer Meldung ein */
- /* wenn Nummer<0 sind alle Warnungen ein */
- {
- int i;
- if(*p!='=') error(4,"-warn");
- i=atoi(p+1);
- if(i>=err_num) error(159,i);
- if(i<0){
- for(i=0;i<err_num;i++) err_out[i].flags&=~DONTWARN;
- return;
- }else err_out[i].flags&=~DONTWARN;
- }
-
- extern char *copyright;
-
- int main(int argc,char *argv[])
- {
- int i,j,fname=0;
- c_flags_val[9].f=dontwarn;
- c_flags_val[10].f=warn;
- for(i=1;i<argc;i++){
- if(*argv[i]!='-'){ /* kein Flag */
- if(fname){
- error(1);
- }else fname=i;
- }else{
- int flag=0;
- for(j=0;j<MAXCF;j++){
- size_t l;
- if(!c_flags_name[j]) continue;
- l=strlen(c_flags_name[j]);
- if(l>0&&!strncmp(argv[i]+1,c_flags_name[j],l)){
- flag=1;
- if((c_flags[j]&(USEDFLAG|FUNCFLAG))==USEDFLAG){error(2,argv[i]);break;}
- c_flags[j]|=USEDFLAG;
- if(c_flags[j]&STRINGFLAG){
- if(argv[i][l+1]!='='){error(3,argv[i]);}
- c_flags_val[j].p=&argv[i][l+2];
- }
- if(c_flags[j]&VALFLAG){
- if(argv[i][l+1]!='='){error(4,argv[i]);}
- c_flags_val[j].l=atol(&argv[i][l+2]);
- }
- if(c_flags[j]&FUNCFLAG) c_flags_val[j].f(&argv[i][l+1]);
- }
- }
- for(j=0;j<MAXGF;j++){
- size_t l;
- if(!g_flags_name[j]) continue;
- l=strlen(g_flags_name[j]);
- if(l>0&&!strncmp(argv[i]+1,g_flags_name[j],l)){
- flag=1;
- if((g_flags[j]&(USEDFLAG|FUNCFLAG))==USEDFLAG){error(2,argv[i]);break;}
- g_flags[j]|=USEDFLAG;
- if(g_flags[j]&STRINGFLAG){
- if(argv[i][l+1]!='='){error(3,argv[i]);}
- g_flags_val[j].p=&argv[i][l+2];
- }
- if(g_flags[j]&VALFLAG){
- if(argv[i][l+1]!='='){error(4,argv[i]);}
- g_flags_val[j].l=atol(&argv[i][l+2]);
- }
- if(g_flags[j]&FUNCFLAG) g_flags_val[j].f(&argv[i][l+1]);
- }
- }
- if(!flag){error(5,argv[i]);}
- }
- }
- if(!(c_flags[6]&USEDFLAG)) printf(copyright);
- if(!(c_flags[17]&USEDFLAG)) pp_init();
- if(!(c_flags[8]&USEDFLAG)) c_flags_val[8].l=10; /* max. Fehlerzahl */
- if(!fname){error(6);}
- inname=argv[fname];
- strcpy(errfname,inname); /* das hier ist Muell - wird noch geaendert */
- if(!init_cg()) exit(EXIT_FAILURE);
- if(c_flags[17]&USEDFLAG){
- in[0]=fopen(inname,"r");
- if(!in[0]) {error(7,inname);}
- }else{
- if(!pp_include(inname)) error(7,inname);
- }
- if(!(c_flags[18]&USEDFLAG)&&!(c_flags[5]&USEDFLAG)){
- out=open_out(inname,"asm");
- if(!out){
- if(c_flags[17]&USEDFLAG){
- fclose(in[0]);
- }else{
- pp_free();
- }
- exit(EXIT_FAILURE);
- }
- }
- if(c_flags[2]&USEDFLAG) ic1=open_out(inname,"ic1");
- if(c_flags[3]&USEDFLAG) ic2=open_out(inname,"ic2");
- if(c_flags[18]&USEDFLAG) ppout=open_out(inname,"i");
- if(c_flags[4]&USEDFLAG) DEBUG=c_flags_val[4].l; else DEBUG=0;
- switch_count=0;break_label=0;
- *string=0;s=string;line=0;
- killsp();
- nesting=-1;enter_block();
- translation_unit();
- }
-
- void prd(FILE *o,struct Typ *p)
- /* Gibt einen Typ auf dem Bildschirm aus */
- {
- int f;
- if(!p) {fprintf(o,"empty type ");return;}
- f=p->flags;
- /* fprintf(o,"(Sizeof=%d,flags=%d)",szof(p),f);*/
- if(type_uncomplete(p)) {fprintf(o,"incomplete ");}
- if(f&CONST) {fprintf(o,"const ");f&=~CONST;}
- if(f&STRINGCONST) {fprintf(o,"string-const ");f&=~STRINGCONST;}
- if(f&VOLATILE) {fprintf(o,"volatile ");f&=~VOLATILE;}
- if(f&UNSIGNED) {fprintf(o,"unsigned ");f&=~UNSIGNED;}
- if(f==FUNKT) {fprintf(o,"function with parameters (");
- prl(o,p->exact);
- fprintf(o,") returning ");prd(o,p->next);return;}
- if(f==STRUCT){fprintf(o,"struct with components {");
- prl(o,p->exact);fprintf(o,"} ");
- return;
- }
- if(f==UNION) {fprintf(o,"union with components {");
- prl(o,p->exact);fprintf(o,"} ");
- return;
- }
- if(f==POINTER) {fprintf(o,"pointer to ");prd(o,p->next);return;}
- if(f==ARRAY) {fprintf(o,"array [size %d] of ",p->size);prd(o,p->next);return;}
- fprintf(o,"%s",typname[f]);
- }
- void prl(FILE *o,struct struct_declaration *p)
- /* Gibt eine struct_declaration auf dem Bildschirm aus */
- {
- int i;
- for(i=0;i<p->count;i++) {fprintf(o," %d.:",i); prd(o,(*p->sl)[i].styp);}
- }
- void freetyp(struct Typ *p)
- /* Gibt eine Typ-Liste frei, aber keine struct_declaration oder so */
- {
- int f;struct Typ *merk;
- if(DEBUG&8){printf("freetyp: ");prd(stdout,p);printf("\n");}
- while(p){
- merk=p->next;
- f=p->flags&15;
- if(merk&&f!=ARRAY&&f!=POINTER&&f!=FUNKT){ierror(0);return;}
- free(p);
- p=merk;
- }
- }
- void cpbez(char *m)
- /* kopiert den naechsten Bezeichner von s nach m */
- {
- char *last=m+MAXI-1;int warned=0;
- if(DEBUG&128) printf("Before cpbez:%s\n",s);
- while(isalpha((unsigned char)*s)||isdigit((unsigned char)*s)||*s=='_'){
- if(m<last){
- *m++=*s++;
- }else{
- s++;
- if(!warned){
- error(206,MAXI-1);
- warned=1;
- }
- }
- }
- *m=0;
- if(DEBUG&128) printf("After cpbez:%s\n",s);
- }
- void cpnum(char *m)
- /* kopiert die naechste int-Zahl von s nach m */
- /* muss noch erheblich erweiter werden */
- {
- if(DEBUG&128) printf("Before cpnum:%s\n",s);
- while(isdigit((unsigned char)*s)) *m++=*s++;
- *m++=0;
- if(DEBUG&128) printf("After cpnum:%s\n",s);
-
- }
- void killsp(void)
- /* Ueberspringt Fuellzeichen */
- /* noch einige unschoene Dinge drin */
- {
- int r;
- if(DEBUG&128) printf("Before killsp:%s\n",s);
- if(eof) raus();
- while(isspace((unsigned char)*s)){
- /* if(*s=='\n') {line++;if(DEBUG&1) printf("Line %d\n",line);}*/
- s++;
- }
- if(*s==0){
- do{
- if(c_flags[17]&USEDFLAG) r=(fgets(string,MAXINPUT,in[0])!=0);
- else r=pp_nextline();
- if(!r){
- /*raus();*/
- if(DEBUG&1) printf("nextline/fgets returned 0\n");
- s=string;*s=0;
- eof=1;
- return;
- }else{
- line++;
- read_new_line=1;
- if(DEBUG&1) printf("Line %d\n",line);}
- if(!strncmp("#pragma",string,7)) error(163);
- if(!strncmp("#pragma only-inline on",string,22)){
- if(DEBUG&1) printf("only-inline on\n");
- only_inline=1;
- }
- if(!strncmp("#pragma only-inline off",string,23)){
- if(DEBUG&1) printf("only-inline off\n");
- only_inline=2;
- }
- if(!strncmp("#pragma type ",string,13)){
- /* Typ eines Ausdrucks im Klartext ausgeben */
- np tree;
- s=string+13;
- tree=expression();
- if(tree&&type_expression(tree)){
- printf("type of %s is:\n",string+13);
- prd(stdout,tree->ntyp);printf("\n");
- }
- if(tree) free_expression(tree);
-
- }
- if(!strncmp("#pragma tree ",string,13)){
- /* gibt eine expression aus */
- np tree;
- s=string+13;
- tree=expression();
- if(tree&&type_expression(tree)){
- printf("tree of %s is:\n",string+13);
- pre(stdout,tree);printf("\n");
- }
- if(tree) free_expression(tree);
- }
- if(string[0]=='#'&&isspace((unsigned char)string[1])&&isdigit((unsigned char)string[2])){
- sscanf(string+2,"%d \" %[^\"]",&line,errfname);
- if(DEBUG&1) printf("new line: %d (file=%s)\n",line,errfname);
- line--;
- }
- if(!strncmp("#line ",string,6)){
- sscanf(string+6,"%d \" %[^\"]",&line,errfname);
- if(DEBUG&1) printf("new line: %d (file=%s)\n",line,errfname);
- line--;
- }
- s=string;
- }while(*s=='#');
- killsp();
- }
- if(DEBUG&128) printf("After killsp:%s\n",s);
- }
- int szof(struct Typ *t)
- /* liefert die benoetigte Groesse eines Typs in Bytes */
- /* maschinenabhaengig */
- {
- int i=t->flags,j,size,m,f;
- /* if(type_uncomplete(t)){
- error(176);
- return(0);
- }*/
- if((i&15)==POINTER) return(4);
- if((i&15)==ARRAY) return((t->size)*szof(t->next));
- if((i&15)==UNION){
- for(j=0,size=0;j<t->exact->count;j++){
- m=szof((*t->exact->sl)[j].styp);
- if(m==0) return(0);
- if(m>size) size=m;
- }
- return(((size+align[UNION]-1)/align[UNION])*align[UNION]); /* align */
- }
- if((i&15)==STRUCT){
- for(j=0,size=0;j<t->exact->count;j++){
- m=szof((*t->exact->sl)[j].styp);
- if(m==0) return(0);
- f=((*t->exact->sl)[j].styp->flags)&15;
- size=((size+align[f]-1)/align[f])*align[f];
- size+=m;
- }
- return(((size+align[STRUCT]-1)/align[STRUCT])*align[STRUCT]);
- }
- if(DEBUG&2) printf("sizeof(%d)=%d\n",i&15,sizetab[i&15]);
- return(sizetab[i&15]);
- }
- void enter_block(void)
- /* Setzt Zeiger/Struckturen bei Eintritt in neuen Block */
- {
- if(nesting>=MAXN){error(9,nesting);return;}
- nesting++;
- if(DEBUG&1) printf("enter block %d\n",nesting);
- first_ilist[nesting]=last_ilist[nesting]=0;
- first_sd[nesting]=last_sd[nesting]=0;
- first_si[nesting]=last_si[nesting]=0;
- first_var[nesting]=last_var[nesting]=0;
- if(nesting==1){
- first_llist=last_llist=0;
- first_clist=last_clist=0;
- merk_varf=merk_varl=0;
- merk_ilistf=merk_ilistl=0;
- merk_sif=merk_sil=0;
- /* struct-declarations erst ganz am Schluss loeschen. Um zu vermeiden, */
- /* dass struct-declarations in Prototypen frei werden und dann eine */
- /* spaetere struct, dieselbe Adresse bekommt und dadurch gleich wird. */
- /* Nicht sehr schoen - wenn moeglich noch mal aendern. */
- /* merk_sdf=merk_sdl=0;*/
- afterlabel=0;
- }
- }
- void leave_block(void)
- /* Setzt Zeiger/Struckturen bei Verlassen eines Blocks */
- {
- int i;
- for(i=1;i<=MAXR;i++)
- if(regbnesting[i]==nesting) regsbuf[i]=0;
-
- if(nesting<0){error(10);return;}
- if(DEBUG&1) printf("leave block %d\n",nesting);
- if(nesting>0){
- if(merk_varl) merk_varl->next=first_var[nesting]; else merk_varf=first_var[nesting];
- if(last_var[nesting]) merk_varl=last_var[nesting];
- if(merk_sil) merk_sil->next=first_si[nesting]; else merk_sif=first_si[nesting];
- if(last_si[nesting]) merk_sil=last_si[nesting];
- if(merk_sdl) merk_sdl->next=first_sd[nesting]; else merk_sdf=first_sd[nesting];
- if(last_sd[nesting]) merk_sdl=last_sd[nesting];
- if(merk_ilistl) merk_ilistl->next=first_ilist[nesting]; else merk_ilistf=first_ilist[nesting];
- if(last_ilist[nesting]) merk_ilistl=last_ilist[nesting];
- }
- if(nesting==1){
- if(merk_varf) gen_vars(merk_varf);
- if(first_llist) free_llist(first_llist);
- if(first_clist) free_clist(first_clist);
- if(merk_varf) free_var(merk_varf);
- if(merk_sif) free_si(merk_sif);
- /* struct-declarations erst ganz am Schluss loeschen. Um zu vermeiden, */
- /* dass struct-declarations in Prototypen frei werden und dann eine */
- /* spaetere struct, dieselbe Adresse bekommt und dadurch gleich wird. */
- /* Nicht sehr schoen - wenn moeglich noch mal aendern. */
- /* if(merk_sdf) free_sd(merk_sdf);*/
- if(merk_ilistf) free_ilist(merk_ilistf);
- }
- if(nesting==0){
- /* struct-declarations erst ganz am Schluss loeschen. Um zu vermeiden, */
- /* dass struct-declarations in Prototypen frei werden und dann eine */
- /* spaetere struct, dieselbe Adresse bekommt und dadurch gleich wird. */
- /* Nicht sehr schoen - wenn moeglich noch mal aendern. */
- if(merk_sdf) free_sd(merk_sdf);
- if(first_var[0]) gen_vars(first_var[0]);
- if(first_var[0]) free_var(first_var[0]);
- if(first_sd[0]) free_sd(first_sd[0]);
- if(first_si[0]) free_si(first_si[0]);
- if(first_ilist[0]) free_ilist(first_ilist[0]);
- }
- nesting--;
- }
- void pra(FILE *f,struct argument_list *p)
- /* Gibt argument_list umgekehrt auf Bildschirm aus */
- {
- if(p->next){ pra(f,p->next);fprintf(f,",");}
- if(p->arg) pre(f,p->arg);
- }
- void pre(FILE *f,np p)
- /* Gibt expression auf Bildschirm aus */
- {
- int c;
- c=p->flags;
- if(p->sidefx) fprintf(f,"/");
- if(p->lvalue) fprintf(f,"|");
- if(c==CALL){fprintf(f,"call-function(");pre(f,p->left);fprintf(f,")(");
- if(p->alist) pra(f,p->alist);
- fprintf(f,")");return;}
- if(c==CAST){fprintf(f,"cast(");pre(f,p->left);
- fprintf(f,"->");prd(f,p->ntyp);
- fprintf(f,")");return;}
- if(c==MEMBER){if(p->identifier) fprintf(f,".%s",p->identifier);return;}
- if(c==IDENTIFIER){if(p->identifier) fprintf(f,"%s",p->identifier);
- fprintf(f,"+");printval(f,&p->val,LONG,1); return;}
- fprintf(f,"%s(",ename[c]);
- if(p->left) pre(f,p->left);
- if(p->right){
- fprintf(f,",");
- pre(f,p->right);
- }
- fprintf(f,")");
- if(c==CEXPR||c==PCEXPR){fprintf(f,"(value="); printval(f,&p->val,p->ntyp->flags,1); fprintf(f,")");}
- }
- void printval(FILE *f,union atyps *p,int t,int verbose)
- /* Gibt atyps aus */
- {
- if(t==CHAR){if(verbose)fprintf(f,"C");vlong=zc2zl(p->vchar);printzl(f,vlong);}
- if(t==(UNSIGNED|CHAR)){if(verbose)fprintf(f,"UC");vulong=zuc2zul(p->vuchar);printzul(f,vulong);}
- if(t==SHORT){if(verbose)fprintf(f,"S");vlong=zs2zl(p->vshort);printzl(f,vlong);}
- if(t==(UNSIGNED|SHORT)){if(verbose) fprintf(f,"US");vulong=zus2zul(p->vushort);printzul(f,vulong);}
- if(t==FLOAT){if(verbose)fprintf(f,"F");vdouble=zf2zd(p->vfloat);printzd(f,vdouble);}
- if(t==DOUBLE){if(verbose)fprintf(f,"D");printzd(f,p->vdouble);}
- if(t==INT){if(verbose)fprintf(f,"I");vlong=zi2zl(p->vint);printzl(f,vlong);}
- if(t==LONG){if(verbose)fprintf(f,"L");printzl(f,p->vlong);}
- if(t==(UNSIGNED|INT)){if(verbose)fprintf(f,"UI");vulong=zui2zul(p->vuint);printzul(f,vulong);}
- if(t==(UNSIGNED|LONG)){if(verbose)fprintf(f,"UL");printzul(f,p->vulong);}
- /* das hier ist nicht wirklich portabel */
- if(t==POINTER){if(verbose)fprintf(f,"P");vulong=zp2zul(p->vpointer);printzul(f,vulong);}
- }
- void pric2(FILE *f,struct IC *p)
- /* Gibt ein IC aus */
- {
- if(p->next&&p->next->prev!=p) {ierror(0);exit(EXIT_FAILURE);}
- if(p->code>=LABEL&&p->code<=BRA){
- if(p->code==LABEL) fprintf(f,"L%d",p->typf);
- else fprintf(f,"\t\t%s L%d",ename[p->code],p->typf);
- }else{
- fprintf(f,"\t\t%s ",ename[p->code]);
- if(p->typf&UNSIGNED) fprintf(f,"unsigned ");
- if(p->typf) fprintf(f,"%s ",typname[p->typf&15]);
- probj(f,&p->q1,p->typf,1);
- if(p->q2.flags){fprintf(f,",");probj(f,&p->q2,p->typf,1);}
- if(p->z.flags){fprintf(f,"->");probj(f,&p->z,p->typf,1);}
- if(p->code==ASSIGN||p->code==PUSH||p->code==POP) fprintf(f," size=%d",p->q2.reg);
- if((p->code==SAVEREGS||p->code==RESTOREREGS)&&p->q1.reg) fprintf(f," except %s",regnames[p->q1.reg]);
- }
- fprintf(f,"\n");
- }
- void pric(FILE *f,struct IC *p)
- /* Gibt IC-Liste auf dem Bildschirm aus */
- {
- while(p){
- pric2(f,p);
- /* if(p->q1.am||p->q2.am||p->z.am) ierror(0);*/
- p=p->next;
- }
- }
-
- char *errstr[]={"","warning","error"};
-
- void error(int errn,...)
- /* Behandelt Ausgaben wie Fehler und Meldungen */
- {
- int type=0;
- va_list vl;
- if(err_out[errn].flags&DONTWARN) return;
- va_start(vl,errn);
- if(err_out[errn].flags&WARNING) type=1;
- if(err_out[errn].flags&ERROR) type=2;
- if(c_flags[7]&USEDFLAG){
- if(err_out[errn].flags&ANSIV) type=2; else type=0;
- }
- if(type){
- {if(eof) printf(">EOF\n"); else printf(">%s",string);}
- if(!(c_flags[17]&USEDFLAG)){
- printf("\n");
- printf("%s %d in line %d of \"%s\": ",errstr[type],errn,linenr,filename[incnesting]);
- }else{
- printf("%s %d in line %d of \"%s\": ",errstr[type],errn,line,errfname);
- }
- }
- if(type||(err_out[errn].flags&MESSAGE)){
- vprintf(err_out[errn].text,vl);
- printf("\n");
- }
- va_end(vl);
- if(type==2){
- errors++;
- if(c_flags_val[8].l&&c_flags_val[8].l<=errors)
- {printf("Maximum number of errors reached!\n");raus();}
- }
- if(err_out[errn].flags&FATAL){printf("aborting...\n");raus();}
- }
- void printzl(FILE *f,zlong x)
- /* Konvertiert zlong nach ASCII */
- /* basiert noch einigermassen auf */
- /* Zweierkomplementdarstellung (d.h. -MIN>MAX) */
- /* Ausserdem muss max(abs(long))<=max(unsigned long) */
- {
- zlong zl;zulong zul;
- zl=l2zl(0L);
- if(zlleq(x,zl)&&!zleq(x)){
- fprintf(f,"-");zl=zul2zl(t_max[LONG]);
- if(zlleq(x,zlneg(zl))&&!zleqto(x,zlneg(zl))){
- /* aufpassen, da -x evtl. >LONG_MAX */
- zul=t_max[LONG];
- x=zladd(x,zl);
- } else zul=ul2zul(0UL);
- x=zlneg(x);
- vulong=zl2zul(x);
- zul=zuladd(zul,vulong);
- }else zul=zl2zul(x);
- printzul(f,zul);
- }
- void printzul(FILE *f,zulong x)
- /* Konvertiert zulong nach ASCII */
- {
- zulong zul;unsigned long l;
- if(DEBUG&64) printf("printzul:%lu\n",x);
- zul=ul2zul(10UL);
- if(!zuleq(zuldiv(x,zul))) printzul(f,zuldiv(x,zul));
- zul=zulmod(x,zul);l=zul2ul(zul);
- fprintf(f,"%c",(int)(l+'0'));
- }
- void printzd(FILE *f,zdouble x)
- /* Konvertiert zdouble nach ASCII, noch nicht fertig */
- {
- fprintf(f,"sorry, floating point not yet");
- }
- FILE *open_out(char *name,char *ext)
- /* Haengt ext an name an und versucht diese File als output zu oeffnen */
- {
- char *s,*p;FILE *f;
- s=mymalloc(strlen(name)+strlen(ext)+2);
- strcpy(s,name);
- p=s+strlen(s);
- while(p>=s){
- if(*p=='.'){*p=0;break;}
- p--;
- }
- strcat(s,".");
- strcat(s,ext);
- f=fopen(s,"w");
- if(!f) printf("Couldn't open <%s> for output!\n",s);
- free(s);
- return(f);
- }
- void *mymalloc(size_t size)
- /* Belegt Speicher mit Abfrage */
- {
- void *p;static int safe;
- /* Um ein Fehlschlagen bei size==0 zu vermeiden; nicht sehr schoen, */
- /* aber das einfachste... */
- if(size==0) size=1;
- if(!(p=malloc(size))){
- error(12);
- raus();
- }
- return(p);
- }
-
-